package com.gateway.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.GatewayFilterSpec;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.gateway.route.builder.UriSpec;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import reactor.core.publisher.Mono;

import java.util.function.Function;

/**
 * @author linzf
 */
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class GatewayDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayDemoApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        RewritePathGatewayFilterFactory.Config config = new RewritePathGatewayFilterFactory.Config();
        config.setRegexp("/api-b/(?<segment>.*)");
        config.setReplacement("/${segment}");
        GatewayFilter filter = new RewritePathGatewayFilterFactory()
                .apply(config);
        Function<GatewayFilterSpec, UriSpec> fn = gatewayFilterSpec -> gatewayFilterSpec.filter(filter);

        RewritePathGatewayFilterFactory.Config configV1 = new RewritePathGatewayFilterFactory.Config();
        configV1.setRegexp("/v1/(?<segment>.*)");
        configV1.setReplacement("/${segment}");
        GatewayFilter filterV1 = new RewritePathGatewayFilterFactory()
                .apply(configV1);
        Function<GatewayFilterSpec, UriSpec> fnV1 = gatewayFilterSpec -> gatewayFilterSpec.filter(filterV1);
        return builder.routes()
                .route(r -> r.path("/api-b/**").filters(fn).uri("lb://CONSUMER-DEMO"))
                .route(r -> r.path("/v1/**").filters(fnV1).uri("lb://USER-CENTER-CONSUMER"))
                .build();
    }


    @Bean
    RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(1, 2);
    }

    /**
     * 自定义限流标志的key，多个维度可以从这里入手
     * exchange对象中获取服务ID、请求信息，用户信息等
     */
    @Bean
    KeyResolver remoteAddrKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
    }



}
